from django.shortcuts import render
from rest_framework import viewsets,views,status
from rest_framework.response import Response
from .models import Project,Host,Api,ApiRunRecord,Case,CaseArgument,ApiArgument,CaseRunRecord,CaseApiRunRecord
from rest_framework.permissions import IsAuthenticated
from .serializers import ProjectSerializer,HostSerializer,ApiSerializer,ApiRunRecordSerializer,CaseSerializer,CaseRunRecordSerializer
from apps.zlauth.authorizations import JWTAuthentication
from . import zlrequest
from utils import dictor
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer
import json

class IndexView(views.APIView):
    def get(self,request):
        project_count = Project.objects.count()
        api_count = Api.objects.count()
        case_count = Case.objects.count()
        api_run_count = ApiRunRecord.objects.count()
        case_run_count = CaseRunRecord.objects.count()
        data = {
            "data": {
                'project': project_count,
                'api': api_count,
                'case': case_count,
                'api_record': api_run_count,
                'case_record': case_run_count
            }
        }
        return Response(data)

class ProjectViewSets(viewsets.ModelViewSet):
    queryset = Project.objects.all()
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    serializer_class = ProjectSerializer

class HostViewSets(viewsets.ModelViewSet):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    queryset = Host.objects.all()
    serializer_class = HostSerializer

class ApiViewSets(viewsets.ModelViewSet):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    queryset = Api.objects.all()
    serializer_class = ApiSerializer



class CaseViewSets(viewsets.ModelViewSet):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    queryset = Case.objects.all()
    serializer_class = CaseSerializer


class RunApiView(views.APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    def post(self,request,api_id):
        api = Api.objects.get(pk=api_id)
        resp = zlrequest.request(api)
        runrecord = ApiRunRecord.objects.create(
            url=resp.url,
            http_method=resp.request.method,
            return_code=resp.status_code,
            return_content=resp.text,
            data=resp.request.body,
            headers=api.headers,
            api=api,
            user=request.user
        )
        serializer = ApiRunRecordSerializer(runrecord)
        return Response(serializer.data)

class ApiView(views.APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    # queryset = Api.objects.all()
    # serializer_class = ApiSerializer
    def post(self,request):
        serializer=ApiSerializer(data=request.data)
        if serializer.is_valid():
            name=request.data.get('name')
            host=request.data.get('host')
            if(request.data.get('data')):
                data=request.data.get('data')
            if(request.data.get('jsonValue')):
                data=request.data.get('jsonValue')
            http_method=request.data.get('http_method')
            project_id=request.data.get('project_id')
            headers=request.data.get('headers')
            host_id=request.data.get('host_id')
            path=request.data.get('path')
            expect_content=request.data.get('expect_content')
            expect_code=request.data.get('expect_code')
            description=request.data.get('description')
            api=Api.objects.create(
                name=name,
                data=data,
                http_method=http_method,
                project_id=project_id,
                headers=headers,
                host_id=host_id,
                path=path,
                expect_content=expect_content,
                expect_code=expect_code,
                description=description
            )
            api.save()
            return Response(data=ApiSerializer(api).data)
        else:
            print(serializer.errors)
            return Response(status=status.HTTP_400_BAD_REQUEST)




class CaseView(views.APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    def post(self,request):
        serializer = CaseSerializer(data=request.data)
        if serializer.is_valid():
            name = request.data.get('name')
            description = request.data.get('description')
            arguments = request.data.get('arguments')
            api_list = request.data.get('api_list')
            project_id = request.data.get('project')

            # 先使用那些没有外键的参数，创建case对象！
            case = Case.objects.create(
                name=name,
                description=description,
                project_id=project_id
            )

            # 判断有没有用例参数，如果有，就循环创建用例参数，然后绑定到case对象上
            if arguments:
                for argument in arguments:
                    CaseArgument.objects.create(
                        name=argument['name'],
                        value=argument['value'],
                        case=case
                    )

            # 判断有没有api列表，如果有，然后绑定到case上
            if api_list:
                api_list = sorted(api_list,key=lambda x:x['index'])
                for api in api_list:
                    api_model = Api.objects.get(pk=api['id'])
                    case.api_list.add(api_model)
                    # 判断这个API中有没有参数，如果有，创建并且保存到数据库中
                    api_arguments = api['arguments']
                    if api_arguments:
                        for api_argument in api_arguments:
                            ApiArgument.objects.create(
                                name=api_argument['name'],
                                origin=api_argument['origin'],
                                format=api_argument['format'],
                                api=api_model
                            )
            # 保存case
            case.save()
            return Response(data=CaseSerializer(case).data)
        else:
            print(serializer.errors)
            return Response(status=status.HTTP_400_BAD_REQUEST)

    def put(self,request,case_id):
        serializer = CaseSerializer(data=request.data)
        if serializer.is_valid():
            case = Case.objects.get(pk=case_id)
            name = request.data.get('name')
            description = request.data.get('description')
            arguments = request.data.get('arguments')
            api_list = request.data.get('api_list')

            case.name = name
            case.description = description

            # 修改用例参数
            if arguments:
                argument_model_list = []
                for argument in arguments:
                    argument_id = argument['id']
                    if argument_id:
                        argument_model = CaseArgument.objects.get(pk=argument_id)
                        argument_model.name = argument['name']
                        argument_model.value = argument['value']
                        argument_model.save()
                        argument_model_list.append(argument_model)
                    else:
                        argument_model = CaseArgument.objects.create(
                            name=argument['name'],
                            value=argument['value'],
                            case=case
                        )
                        argument_model_list.append(argument_model)
                # 重新进行赋值
                case.arguments.set(argument_model_list)
            else:
                case.arguments.set([])

            # 修改API
            if api_list:
                api_model_list = []
                for api in api_list:
                    api_model = Api.objects.get(pk=api['id'])
                    if api['arguments']:
                        argument_model_list = []
                        for argument in api['arguments']:
                            argument_id = argument['id']
                            if argument_id:
                                argument_model = ApiArgument.objects.get(pk=argument_id)
                                argument_model.name = argument['name']
                                argument_model.origin = argument['origin']
                                argument_model.format = argument['format']
                                argument_model.save()
                                argument_model_list.append(argument_model)
                            else:
                                argument_model = ApiArgument.objects.create(
                                    name=argument['name'],
                                    origin=argument['origin'],
                                    format=argument['format'],
                                    api=api_model
                                )
                                argument_model_list.append(argument_model)
                        api_model.arguments.set(argument_model_list)
                    else:
                        api_model.arguments.set([])
                    api_model.save()
                    api_model_list.append(api_model)
                case.api_list.set(api_model_list)
            else:
                case.api_list.set([])

            case.save()
            return Response(data=CaseSerializer(case).data)

class RunCaseView(views.APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    def post(self,request,case_id):
        case = Case.objects.get(pk=case_id)
        case_arguments = CaseArgument.objects.filter(case=case)
        case_record = CaseRunRecord.objects.create(case=case)

        # 定义全局参数字典
        global_arguments = {}
        # 从用例参数中提取参数
        for argument in case_arguments:
            global_arguments[argument.name] = argument.value

        # 运行API
        api_model_list = case.api_list.all()
        for api_model in api_model_list:
            resp = zlrequest.request(api_model,global_arguments)
            CaseApiRunRecord.objects.create(
                url=resp.url,
                http_method=resp.request.method,
                headers=resp.request.headers,
                data=resp.request.body,
                user=request.user,
                return_code=resp.status_code,
                return_content=resp.text,
                api=api_model,
                case_record=case_record
            )
            # 把运行后的结果，提取相应的参数
            api_arguments = api_model.arguments.all()
            if api_arguments:
                for api_argument in api_arguments:
                    dictor_data = {}
                    origin = api_argument.origin
                    if origin == 'HEAD':
                        dictor_data = resp.headers
                    elif origin == 'COOKIE':
                        dictor_data = resp.cookies
                    elif origin == 'BODY':
                        dictor_data = resp.json()
                    argument_value = dictor.dictor(dictor_data,api_argument.format)
                    global_arguments[api_argument.name] = argument_value

        serializer = CaseRunRecordSerializer(case_record)
        return Response(serializer.data)

# ?project_id=1&type=case
class RecordView(views.APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    def get(self,request):
        project_id = request.GET.get('project_id')
        record_type = request.GET.get('type')
        if record_type == 'api':
            records = ApiRunRecord.objects.filter(api__project_id=project_id)
            serializer = ApiRunRecordSerializer(records,many=True)
        else:
            records = CaseRunRecord.objects.filter(case__project_id=project_id)
            serializer = CaseRunRecordSerializer(records,many=True)
        return Response(serializer.data)
